#ifndef EXTRA
#define EXTRA
#endif

const char *fmt, *efmt;
int result;

result = dbuf_get_string(o, &fmt);
if (result < 0)
    return result;

if (*fmt)
    fmt = gettext(fmt);

while ((efmt = strchr(fmt, '%')))
{
    int modifier_l;
    int code = get_code(&efmt, &modifier_l);
    int fmt_len = efmt - fmt;
    char block[fmt_len + 1];
    memcpy(block, fmt, fmt_len);
    block[fmt_len] = 0;

    switch (code)
    {
    case '%':
        result = PRINT("%s", block);
        break;
    case 'c':
    case 'd':
    case 'i':
    case 'x':
    case 'u':
    case 'X':
        if (modifier_l)
        case 'p':
        {
            long l;
            result = dbuf_get_long(o, &l);
            if (result < 0)
                return SET_ERRNO(result);
            result = PRINT(block, l);
        }
            else
            {
                int i;
                result = dbuf_get_int(o, &i);
                if (result < 0)
                    return SET_ERRNO(result);
                result = PRINT(block, i);
            }
        break;
    case 'e':
    case 'E':
    case 'f':
    case 'F':
    case 'g':
    case 'G':
    {
        double d;
        result = dbuf_get_double(o, &d);
        if (result < 0)
            return SET_ERRNO(result);
        result = PRINT(block, d);
    }
    break;
    case 's':
    {
        const char* s;
        result = dbuf_get_string(o, &s);
        if (result < 0)
            return SET_ERRNO(result);
        if (*s)
            s = gettext(s);
        result = PRINT(block, s);
    }
    break;
    }
    if (result < 0)
        return SET_ERRNO(result);
    EXTRA
    fmt = efmt;
}
if (*fmt)
{
    result = PRINT("%s", fmt);
    if (result < 0)
        return SET_ERRNO(result);
    EXTRA
}

return SET_ERRNO(result);
#undef PRINT
#undef EXTRA
